package com.meida.msg.provider.service.impl;

import com.meida.common.constants.CommonConstants;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.msg.client.entity.MsgContent;
import com.meida.msg.client.entity.MsgReceive;
import com.meida.msg.client.entity.MsgType;
import com.meida.msg.provider.mapper.MsgReceiveMapper;
import com.meida.msg.provider.service.MsgContentService;
import com.meida.msg.provider.service.MsgReceiveService;
import com.meida.msg.provider.service.MsgTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 消息接收表接口实现类
 *
 * @author flyme
 * @date 2020-02-28
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MsgReceiveServiceImpl extends BaseServiceImpl<MsgReceiveMapper, MsgReceive> implements MsgReceiveService {
    @Resource
    private MsgContentService msgContentService;

    @Autowired
    private MsgTypeService msgTypeService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, MsgReceive receive, EntityMap extra) {
        return ResultBody.ok();
    }


    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<MsgReceive> cq, MsgReceive receive, EntityMap requestMap) {
        initUserMsg();
        cq.select(MsgReceive.class, "msgUserId","readState","createTime");
        cq.select(MsgContent.class, "msgId", "msgTitle", "msgImage", "msgContent", "sendTime");
        cq.eq(MsgReceive.class, "receiveUserId", OpenHelper.getUserId());
        cq.eq(MsgReceive.class, "deleted", CommonConstants.DEL_NO);
        cq.eq(MsgContent.class, "deleted", CommonConstants.DEL_NO);
        cq.createJoin(MsgContent.class);
        cq.orderByDesc("receive.createTime");
        return ResultBody.ok();
    }

    @Override
    public void afterGet(CriteriaQuery cq, EntityMap result) {
        Long msgId = result.getLong("msgId");
        Long msgUserId = result.getLong("msgUserId");
        updatReadState(msgUserId);
        EntityMap content = msgContentService.findById(msgId);
        if (FlymeUtils.isNotEmpty(content)) {
            result.putAll(content);
        }

    }

    /**
     * 更新消息读取状态
     *
     * @param msgUserId
     * @return
     */
    private void updatReadState(Long msgUserId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "readState", CommonConstants.ENABLED);
        cu.eq(true, "msgUserId", msgUserId);
        update(cu);
    }

    public Boolean deleteByMsgId(Long[] msgIds) {
        CriteriaDelete cd = new CriteriaDelete();
        cd.in(true, "msgId", msgIds);
        return remove(cd);
    }

    @Override
    public ResultBody getNoReadMessageInfo(Long userId) {
        int noReadNum = countNoRead(userId);
        EntityMap entityMap = new EntityMap();
        entityMap.put("noReadNum", noReadNum);
        List<EntityMap> systemMsgList = selectNoReadMessage(userId, "SystemMsg");
        entityMap.put("systemMsgList", systemMsgList);
        List<EntityMap> personalMsgList = selectNoReadMessage(userId, "PersonalMsg");
        entityMap.put("personalMsgList", personalMsgList);
        List<EntityMap> systemMaintenanceList = selectNoReadMessage(userId, "SystemMaintenance");
        entityMap.put("systemMaintenanceList", systemMaintenanceList);
        return ResultBody.ok(entityMap);
    }

    @Override
    public int countNoRead(Long userId) {
        CriteriaQuery cq = new CriteriaQuery(MsgReceive.class);
        cq.eq("receiveUserId", userId);
        cq.eq("readState", CommonConstants.DISABLED);
        return count(cq);
    }

    @Override
    public List<EntityMap> selectNoReadMessage(Long userId, String typeCode) {
        MsgType msgType = msgTypeService.findByTypeCode(typeCode);
        CriteriaQuery cq = new CriteriaQuery(MsgReceive.class);
        cq.eq(true, "receiveUserId", userId);
        cq.eq("readState", CommonConstants.DISABLED);
        cq.eq(true, "msgTypeId", msgType.getMsgTypeId());
        cq.createJoin(MsgContent.class).setMainField("msgId").setJoinField("msgId");
        return selectEntityMap(cq);
    }

    /**
     * 初始化用户消息
     */
    private void initUserMsg() {
        Long userId = OpenHelper.getUserId();
        EntityMap params = new EntityMap();
        params.put("receiveUserId", OpenHelper.getUserId());
        List<MsgContent> list = msgContentService.selectNotReceiveByUserId(params);
        if (FlymeUtils.isNotEmpty(list)) {
            List<MsgReceive> receiveList = new ArrayList<>();
            for (MsgContent msgContent : list) {
                MsgReceive receive = new MsgReceive();
                receive.setReceiveUserId(userId);
                receive.setDeleted(CommonConstants.DEL_NO);
                receive.setReadState(CommonConstants.DISABLED);
                receive.setMsgId(msgContent.getMsgId());
                receiveList.add(receive);
            }
            saveBatch(receiveList);
        }
    }
}
